import { HttpService, Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import * as puppeteer from 'puppeteer';
import { Browser, JSHandle, Page, Request } from 'puppeteer';
import { Repository } from 'typeorm';
import { MConstService } from '../mconst/mconst.service';
import { NewsPo } from './interface/news.interface';
import { Statistics } from './interface/statistics.interface';
import { News } from './news.entity';

@Injectable()
export class NewsService {
  private readonly logger = new Logger(NewsService.name);
  constructor(
    @InjectRepository(News)
    private readonly newsRepository: Repository<News>,
    private readonly httpService: HttpService,
    private readonly mConstService: MConstService,
  ) {}

  async list() {
    return await this.newsRepository.find();
  }

  async add(newsPo: NewsPo) {
    this.logger.log('add------------------------------', newsPo.title);
    const count = await this.newsRepository.save(
      this.newsRepository.create(newsPo),
    );
    return count;
  }

  async addWithValidate(newsPo: NewsPo) {
    const item = await this.newsRepository.findOne(newsPo.id);
    if (!item) {
      return await this.add(newsPo);
    } else {
      this.logger.error('news添加失败，已存在数据:' + newsPo.id);
      return item;
    }
  }

  async update(payload) {
    // const group  = await this.newsRepository.findOne(payload.id);
    return await this.newsRepository.save(payload);
  }
  async findLatest() {
    return await this.newsRepository.findOne();
  }

  async puppeteer(): Promise<any> {
    const browser = await puppeteer.launch({
      headless: true,
      args: ['--no-sandbox'],
    });
    const [_, stat] = await Promise.all([
      this.getTimelineJson(browser),
      this.getChinaAndAreaStat(browser),
    ]);
    await browser.close();
    return {
      ...stat,
    };
  }

  // 获取时间json的url
  private async getTimelineJson(browser: Browser): Promise<any> {
    const page: Page = await browser.newPage();
    page.on('request', (request: Request) => {
      const url = request.url();
      if (/^http.*\.json/.test(url)) {
        this.logger.log('request:' + url);
        this.mConstService.setByName('jsonUrl', url.replace(/\?.*$/, ''));
      }
    });
    await page.goto(
      'https://ncov.dxy.cn/ncovh5/view/pneumonia_timeline?whichFrom=dxy',
    );
    await page.close();
    return null;
  }

  // 获取地区感染人数
  private async getChinaAndAreaStat(browser: Browser): Promise<any> {
    if (typeof browser === 'undefined') {
      browser = await puppeteer.launch({
        headless: true,
        args: ['--no-sandbox'],
      });
    }
    const page = await browser.newPage();
    await page.goto('https://ncov.dxy.cn/ncovh5/view/pneumonia');
    const windowHandle = await page.evaluateHandle('window');
    const getAreaStat: JSHandle = await page.evaluateHandle(
      window => window.getAreaStat,
      windowHandle,
    );
    const getStatisticsService: JSHandle = await page.evaluateHandle(
      window => window.getStatisticsService,
      windowHandle,
    );

    const areaStat = await getAreaStat.jsonValue();
    // 全国
    const statisticsService = await getStatisticsService.jsonValue();
    // this.logger.log(areaStat);
    return { areaStat, statisticsService };
  }

  async fetchSituation() {
    const jsonUrl = await this.mConstService.findValueByName('jsonUrl');
    const res = await this.httpService
      .get(`${jsonUrl}?t=${Date.now()}`)
      .toPromise();
    if (res.status !== 200) {
      this.logger.error('请求接口出错');
      throw new Error();
      return;
    }
    const {
      data: { data },
    } = res;
    const latestSend = await this.findLatest();
    this.logger.debug(latestSend && latestSend.id);
    let newsUnsend = [];
    data.find((element, i) => {
      this.logger.log(`遍历数组${i}`);
      if (!latestSend || element.pubDate > latestSend.pubDate) {
        this.addWithValidate(element);
        newsUnsend.push(element);
        return false;
      } else {
        return true;
      }
    });
    this.logger.log('执行完成 ' + newsUnsend.length + '个待发送数据');
    return newsUnsend;
  }
}
